package nju.software.tagmanager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import nju.software.tagmanager.common.context.BaseContext;
import nju.software.tagmanager.common.exception.*;
import nju.software.tagmanager.mapper.RelTagItemMapper;
import nju.software.tagmanager.mapper.TagMapper;
import nju.software.tagmanager.pojo.dto.ItemPageQueryDTO;
import nju.software.tagmanager.pojo.dto.ServiceQueryDTO;
import nju.software.tagmanager.pojo.entity.Item;
import nju.software.tagmanager.pojo.entity.RelCategoryTag;
import nju.software.tagmanager.pojo.entity.RelTagItem;
import nju.software.tagmanager.pojo.entity.Tag;
import nju.software.tagmanager.pojo.vo.ItemVO;
import nju.software.tagmanager.pojo.vo.TagVO;
import nju.software.tagmanager.service.ItemService;
import nju.software.tagmanager.mapper.ItemMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 97942
 * @description 针对表【item(项目表)】的数据库操作Service实现
 * @createDate 2024-01-12 16:03:24
 */
@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item>
        implements ItemService {

    @Resource
    private ItemMapper itemMapper;
    @Resource
    private TagMapper tagMapper;

    @Resource
    private RelTagItemMapper relTagItemMapper;

    @Override

    public List<Item> find(ServiceQueryDTO query) {
        return itemMapper.find(query);
    }

    @Override
    public List<ItemVO> findOnlyFollowing(Integer tagId) {
        return itemMapper.findOnlyFollowing(tagId);
    }

    @Override
    public IPage<ItemVO> search(ItemPageQueryDTO query) {
        try {
            Page<ItemVO> tagVOPage = new Page<>(query.getPage(), query.getLimit());
            IPage<ItemVO> result = itemMapper.search(query, tagVOPage);
            result.getRecords().forEach(item -> {
                item.setTags(tagMapper.findByItemId(item.getId()));
            });
            return result;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new SearchFailureException();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Integer itemId) {
        relTagItemMapper.delete(new QueryWrapper<RelTagItem>()
                .eq("item_id", itemId));
        itemMapper.deleteById(itemId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addItemByTagId(String itemName, Integer tagId) {
        List<Item> items = itemMapper.selectList(new QueryWrapper<Item>().eq("name", itemName));
        Item item = null;
        if (!items.isEmpty()) {
            if (items.size() > 1) {
                // never here cause tagName has a physical unique key,
                // here is just an example for you that reminds you to think twice each condition
                throw new DuplicateItemNameException();
            }
            item = items.get(0);
        }


        //如果是不打标签添加实体，但已存在实体
        if (item != null && tagId == -1) {
            throw new TagAlreadyExistsException();
        }

        //如果查询的实体为空,无论是否打标签,先新增实体
        if (item == null) {
            item = Item.builder()
                    .name(itemName)
                    .createUserId(BaseContext.getCurrentUserId())
                    .build();
            itemMapper.insert(item);
        }

        if (tagId != -1) {
            List<RelTagItem> relTagItems = relTagItemMapper.selectList(new QueryWrapper<RelTagItem>()
                    .eq("item_id", item.getId())
                    .eq("tag_id", tagId));

            if (!relTagItems.isEmpty()) {
                if (relTagItems.size() > 1) {
                    throw new DuplicateTagItemRelationException();
                }
                throw new TagItemRelationAlreadyExistsException();
            }

            RelTagItem rel = RelTagItem.builder()
                    .itemId(item.getId())
                    .tagId(tagId)
                    .build();
            relTagItemMapper.insert(rel);

        }
    }
}




